home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-15 | 58.0 KB | 1,519 lines |
-
-
-
-
-
-
-
-
-
-
- OFF - A 3D Object File Format
-
-
- Randi J. Rost
- 6-November-1986
- Updated 12-October-1989
-
- Digital Equipment Corporation
- Workstation Systems Engineering
- 100 Hamilton Ave.
- Palo Alto, Ca. 94301
-
-
- This document describes the data format
- developed by WSE for the interchange and archiving
- of three-dimensional objects. This format, called
- OFF (for Object File Format), is general, flexi-
- ble, and extensible. It supports ASCII text ver-
- sions of objects for the purpose of interchange,
- and binary versions for efficiency of reading and
- writing. It is assumed that applications will
- develop their own, more efficient format for
- internal storage and operation on three-
- dimensional objects.
-
-
-
-
- _1. _I_n_t_r_o_d_u_c_t_i_o_n
-
- One of the most time-consuming tasks in computer anima-
- tion projects is designing the 3D models that will be used.
- Many computer animation houses have found that owning a
- large number of databases makes it easier for them to take
- on new projects at a lower cost (time and $$$). The cost of
- initially creating an object can be amortized over the
- number of times it can be re-used. It is our intention to
- promote the use of OFF files within (and perhaps even out-
- side of) Digital in an effort to build up our collection of
- useful 3D models.
-
- The file format itself is not limiting: OFF files can
- be used for a wide variety of object types. None of the
- "policy decisions" are hard-wired in the design of the file
- format, or in the support library routines that allow read-
- ing and writing of OFF files. Rather, the policy decisions
- have been left up to the designers since the format supports
- "generic" object definitions. We have developed specific
- conventions for objects that are defined by polygons for use
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 2 -
-
-
- within WSE, and we'd encourage others to adopt these conven-
- tions as well in order to promote the interchange of useful
- object data bases. The _d_x_m_o_d_e_l application (also developed
- by WSE) is an example of an application that permits reading
- and writing of OFF files.
-
- This paper describes the Object File Format itself, the
- conventions we've adopted at WSE, and the library of support
- routines that can be used to read and write OFF files.
-
-
- _2. _D_e_s_i_g_n _G_o_a_l_s _a_n_d _N_o_n-_G_o_a_l_s
-
- Design goals for the Object File Format include:
-
- 1) Simple. Simple cases should be simple. It should be
- possible to type in all the data required for a simple
- object (such as a cube) by hand.
-
- 2) Powerful. The Object File Format should be capable of
- accomodating complicated objects (many vertices,
- polygons, and a wide range of attributes).
-
- 3) Portable. ASCII text file representation required for
- portability across operating systems and hardware.
- This also allows operations on OFF files by familiar
- system utilities (text editors and the like).
-
- 4) Efficient. Binary text file representation required to
- allow efficient reading and writing of OFF files. It
- is assumed that reading/writing an object is a costly
- operation, but reading and writing ASCII data is just
- _t_o_o slow.
-
- 5) General. The format should address the general case of
- the three-dimensional object, not a single particular
- case.
-
- 6) Extensibile. Make sure the format can be easily
- extended to eventually support other primitives such as
- bezier patches.
-
- 7) No Favors. Avoid hard-wiring policy decisions.
- Rather, provide generic building blocks capable of sup-
- porting several styles and document a set of strongly
- encouraged conventions that we have adopted.
-
- There are also things that were specifically non-goals in
- the design of the Object File Format.
-
- 1) Internal Format. The Object File Format is not
- intended to be forced upon applications as an internal
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 3 -
-
-
- format that must be used. Rather, it should be con-
- sidered a means for inputting and outputting object
- descriptions in a device-, language-, and operating
- system-independent format. Applications should feel
- free to develop and maintain the most useful/efficient
- data format they can, and only convert to/from OFF when
- input or output of a standardized object is desired.
-
- 2) Object Conventions. OFF conventions are documented
- only for objects in polygonal form at this point. It
- is anticipated that the Object File Format can be
- easily extended to handle bezier surface patches and
- other primitives in the future.
-
- _3. _O_b_j_e_c_t_s
-
- For the purposes of the Object File Format, we'll adopt
- a very general definition of an _o_b_j_e_c_t. An _o_b_j_e_c_t is simply
- a list of properties (name, description, author, copyright
- information, geometry data, colors, etc.)
-
- The most important information about the object can be
- found in the _h_e_a_d_e_r _f_i_l_e for the object. The header file is
- always an ASCII text file that, by convention, is named
- _n_a_m_e.aoff where _n_a_m_e is the object name. See Appendix B for
- an example of an OFF object header file.
-
- A few of these properties (name, description, author,
- copyright, type) are common to every type of 3D object and
- are considered standard properties. The standard properties
- are built into the routines that manipulate 3D objects. The
- rest of the properties may vary with the type of object, and
- so are defined by convention only.
-
- The _n_a_m_e of an object is used to concisely describe the
- object itself. For example, we have objects named "x29",
- "banana" and "vw". By convention, this name also becomes
- the prefix for OFF data filenames when an object is read or
- written, so it is best to keep it fairly short.
-
- The _d_e_s_c_r_i_p_t_i_o_n is used to more fully describe the
- object itself. It may contain the time and date of creation
- or more prose describing the object.
-
- The _a_u_t_h_o_r should be the name of the person (or com-
- pany, or utility) that created the object. We should always
- try to give credit where credit is due. This field tells
- you who to thank for spiffy objects or whose cage to rattle
- when a problem with an OFF file is discovered.
-
- The _c_o_p_y_r_i_g_h_t field contains information dealing with
- the distribution of the object data. Some object databases
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 4 -
-
-
- will be regarded by a company as proprietary. These objects
- should not be copied or distributed without consent. Other
- objects (vw, x29) were developed by companies or individuals
- and can be copied or used as long as the copyright notice
- appears and proper credit is given. Still other objects
- (cube, sphere, etc.) have been placed in the public domain.
- We have tried to be as careful as possible in preserving
- copyright and author information for the objects we have
- collected, but sometimes the information was lost or una-
- vailable. Be sure and honor copyright notices. If you
- don't, you (or your company) could end up in big trouble.
-
- The _t_y_p_e field contains the type of the object. For
- now, only one type of object is supported: polygon objects.
- It is anticipated that polyline and surface patch-type
- objects will be supported in the future as well.
-
- Also contained in the object header file are lines that
- describe the various properties of the object. Each line in
- the object header file that describes an attribute of the
- object other than a standard attribute must contain the pro-
- perty name, the property type, the data format and either a
- file name or a string containing default data, depending on
- the property type. Each of these four items is an ASCII
- string, separated by white space.
-
- The _p_r_o_p_e_r_t_y _n_a_m_e uniquely describes the property.
- Property names for which we have defined conventions (see
- Appendix A) include geometry, polygon_colors, vertex_colors,
- back_faces, vertex_order, polygon_normals, vertex_normals,
- diffuse_coef, specular_coef, and specular_power.
-
- OFF currently supports four _p_r_o_p_e_r_t_y _t_y_p_e_s: _d_e_f_a_u_l_t,
- _g_e_n_e_r_i_c, _i_n_d_e_x_e_d, and _i_n_d_e_x_e_d__p_o_l_y. If a property is indi-
- cated to be of type _d_e_f_a_u_l_t, the part of the line after the
- data format is assumed to contain some default data that
- will be applied to the entire object. For instance, it may
- make sense to give the entire object a default color and
- default diffuse and specular coefficients.
-
- If the property type is either generic, indexed, or
- indexed_poly (described more fully below), the remainder of
- the line is taken to be a file name that can be opened and
- read to obtain the information for the property.
-
- The data format indicates what type of data will be
- found on the remainder of the line if the property type is
- default, otherwise what kind of data will be found in the
- specified file. The data format is a string of characters
- (no spaces) that indicate the order and type of the data.
- Supported primitive data types are:
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 5 -
-
-
- f - A number stored internally as a 32-bit floating point
- number
-
- d - A number stored internally as a 64-bit double-precision
- floating point number
-
- i - A number stored internally as a 32-bit integer value
-
- h - A number stored internally as a 16-bit integer value
-
- b - A number stored internally as an 8-bit integer value
-
- s - A 32-bit pointer to a null-terminated string of charac-
- ters
-
- If, for instance, you were interested in using 32-bit
- floating values for r, g, and b default color values, you
- might have a line in the object header file that reads
-
- polygon_colors default fff 1.0 0.8 0.0
-
-
- It is important to understand that in all cases, the
- "string" (s) data primitive will indicate a pointer to a
- string that is stored internally in the data block for an
- object and not the string itself.
-
- _4. _A_S_C_I_I _P_r_o_p_e_r_t_y _F_i_l_e_s
-
- OFF supports ASCII text files as a way of providing for
- language-, hardware-, and operating system-independent
- object data files. The three types of data files currently
- supported by OFF are generic, indexed, and indexed_poly.
-
- _4._1. _G_e_n_e_r_i_c _F_i_l_e_s
-
- Generic files contain only a _c_o_u_n_t value followed by
- _c_o_u_n_t data items of the type specified by the data format.
- Each data item can be comprised of some combination of the
- primitive data types described in Section 3. Generic data
- files are useful for storing attributes which are unique at
- every vertex or polygon (such as color or normals).
-
- String data items in ASCII generic files may not con-
- tain spaces or other white space. 8-bit integers must be
- listed in the range 0-255.
-
- See Appendix D for an example of an ASCII generic data
- file.
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 6 -
-
-
- _4._2. _I_n_d_e_x_e_d _F_i_l_e_s
-
- Indexed files make use of a list of indices in order to
- reduce the amount of data required to store a property, and
- to provide a useful level of indirection. For instance,
- indexed files are commonly used to maintain per-polygon
- color information. If an object has just five colors, the
- indexed data file would contain the list of the five colors
- followed by an index from one to five for each of the
- polygons in the object. If an application maintains the
- indirection, it is possible for the user to easily select
- five different colors to be used on the model.
-
- An indexed file begins with two integers separated by
- white space: the number of data items and the number of
- indices that will be provided. Following these two values
- is the list of data items that is to be used. Each data
- item in this list can be some combination of the primitive
- types described in Section 3. Following the data items is a
- list of indices each of which is a pointer to one of the
- items in the list of data items. The list of data items is
- assumed to begin starting at one, not zero.
-
-
- _4._3. _I_n_d_e_x_e_d__P_o_l_y _F_i_l_e_s
-
- Indexed_poly files take advantage of a connectivity
- list to reduce the amount of information needed to store a
- list of polylines, polygons, or normals. The unique
- geometry items (e.g., vertices) are listed in the first part
- of the file. Following this list is a connectivity list.
- Each line in the connectivity list contains a _c_o_u_n_t value
- followed by _c_o_u_n_t indices (pointers) to information in the
- geometry list. (Items in the geometry list are indexed
- starting from one, not zero.)
-
- The first line of an indexed_poly data file contains
- three integers, separated by white space. The first number
- on this line indicates the number of data items
- (vertices/normals) that follow, the second number indicates
- the number of polylines/polygons that follow the data list,
- and the third indicates the total number of edges that are
- contained in the polyline/polygon connectivity list.
-
- String data items in ASCII indexed_poly files may not
- contain spaces or other white space. 8-bit integers must be
- listed in the range 0-255.
-
- See Appendix C for an example of an ASCII indexed_poly
- file.
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 7 -
-
-
- _5. _B_i_n_a_r_y _O_F_F _F_i_l_e_s
-
- The same three types of data files described above are
- also supported in binary format. There are a few minor
- differences.
-
-
- _5._1. _G_e_n_e_r_i_c _F_i_l_e_s
-
- Binary generic files begin with the first 32-bit word
- equal to OFF_GENERIC_MAGIC as defined in the include file
- _o_f_f._h. The second word in the file is the _c_o_u_n_t (number of
- data items in the file). Following the _c_o_u_n_t is the data
- itself.
-
- The data format in the header file describes the primi-
- tives that make up each data item in the list. Within each
- data item, floats, doubles, 32-bit integers, and string
- pointers will all begin on a word boundary. 16-bit integers
- will all begin on a half-word boundary. Thus, if your data
- format for the data items in a generic data file is "bbb"
- (three byte values), each data item will be stored as three
- bytes followed by a null byte so that each data item will
- begin on a word boundary. Strings begin with a 32-bit _c_o_u_n_t
- followed by _c_o_u_n_t characters followed by a null character.
- The string is null-padded so it will end on a word boundary.
-
- (It is assumed that for strings, the length will be
- read and then the necessary memory will be allocated and the
- string read in. This eliminates a problem with having
- variable-length data in the data files. Anyway, strings in
- files are really only there for symmetry with default
- values, where strings are really useful. The performance
- implications for files containing strings will probably be
- enough to prevent people from using them.)
-
-
-
- _5._2. _I_n_d_e_x_e_d _F_i_l_e_s
-
- Binary indexed files begin with the first 32-bit word
- equal to OFF_INDEXED_MAGIC as defined in the include file
- _o_f_f._h. The second word in the file is the _c_o_u_n_t (number of
- data items in the file). The third word in the file is
- _n_u_m__i_n_d_i_c_e_s (number of indices in the index list).
-
- Following these two integers is the data for the data
- item list. Each item in the data item list will begin on a
- word boundary. The data format in the header file describes
- the primitives that make up each data item in the list.
- Within each data item, floats, doubles, 32-bit integers, and
- string pointers will all begin on a word boundary. 16-bit
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 8 -
-
-
- integers will all begin on a half-word boundary. Thus, if
- your data format for the data items in an indexed data file
- is "bbb" (three byte values), each data item will be stored
- as three bytes followed by a null byte so that each data
- item will begin on a word boundary. Strings begin with a
- 32-bit _c_o_u_n_t followed by _c_o_u_n_t characters followed by a null
- character. The string is null-padded so it will end on a
- word boundary.
-
- Following the data item list is a list of index values.
- This list will also begin on a word boundary, however, the
- index values within this list are short integers and will be
- packed two to each 32-bit word.
-
-
- _5._3. _I_n_d_e_x_e_d__P_o_l_y _F_i_l_e_s
-
- Binary indexed_poly files begin with the first 32-bit
- word equal to OFF_INDEXED_POLY_MAGIC as defined in the
- include file off.h. The second word is the number of data
- items in the vertex list (_n_p_t_s), the third word is the
- number of polylines/polygons in the list (_n_p_o_l_y_s), and the
- fourth word is the number of edges contained in the connec-
- tivity list (_n_c_o_n_n_e_c_t_s).
-
- Starting at the fifth word in the file is a list of
- _n_p_t_s data items, followed by _n_p_o_l_y_s short integers contain-
- ing polyline/polygon vertex counts, followed by _n_c_o_n_n_e_c_t_s
- short integers which are indices into the array of data
- items. (This arrangement is slightly different than that
- used for indexed_poly files in ASCII format for efficiency
- reasons.)
-
- The same restrictions that apply to the data types for
- generic binary files apply to indexed_poly binary files as
- well. In addition, the vertex count array which follows the
- geometry data in an indexed_poly file will always begin on a
- word boundary. The connectivity array that follows the ver-
- tex count array will not necessarily start on a word boun-
- dary, but will always begin _n_p_o_l_y_s * _s_i_z_e_o_f(_s_h_o_r_t) bytes
- after the start of the vertex count array.
-
-
- _6. _O_f_f._a _a_n_d _O_b_j_e_c_t_s._h
-
- An include file and a library of routines has been pro-
- vided for UNIX/C programmers to more easily manipulate OFF
- files. The basic concepts of "reading" and "writing" OFF
- files are supported in this library of routines. The
- library is a software layer on top of the operating system
- file I/O interface, with special knowledge of OFF files.
- This subroutine library provides a mechanism for accessing
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 9 -
-
-
- the syntactical elements of an object file, but makes no
- attempt to understand the semantics. Higher level inter-
- faces can be layered on top.
-
- The subroutine library refers to an object as a pointer
- to an _O_F_F_O_b_j_D_e_s_c. This structure contains a pointer to the
- first property in the property list. It is defined as fol-
- lows:
-
- typedef struct
- {
- OFFProperty *FirstProp; /* Pointer to first property in list */
- } OFFObjDesc;
-
-
- The information that describes the object is contained
- in a linked list of property structures. The first such
- structure in the list is pointed at by an _O_F_F_O_b_j_D_e_s_c struc-
- ture. The property structures have the form:
-
- typedef struct _OFFProp
- {
- char PropName[40];
- int PropType;
- char PropFileName[256];
- int PropCount;
- char DataFormat[40];
- char *PropData;
- struct _OFFProp *NextProp;
- } OFFProperty;
-
-
- _P_r_o_p_N_a_m_e contains a string defining one of the property
- types for which a convention has been defined. This
- includes the property names "name", "author", "description",
- "copyright", "comment", "geometry", "polygon_colors",
- "polygon_normal", etc. For a complete list of property
- names, see Appendix A. (The special attribute type "com-
- ment" is supported so that blank lines and comment lines can
- be preserved if an object file is read and then written.)
-
- The _P_r_o_p_T_y_p_e field contains a value equal to
- _O_F_F__D_E_F_A_U_L_T__D_A_T_A, _O_F_F__G_E_N_E_R_I_C__D_A_T_A, _O_F_F__I_N_D_E_X_E_D__D_A_T_A, or
- _O_F_F__I_N_D_E_X_E_D__P_O_L_Y__D_A_T_A which defines the basic type for the
- property.
-
- The _P_r_o_p_F_i_l_e_N_a_m_e is required if _P_r_o_p_T_y_p_e is something
- other than _O_F_F__D_E_F_A_U_L_T__D_A_T_A. It contains a string
- representing the name of the file to be read/written for
- this attribute. This file name should _n_o_t contain a path
- leading up to the file itself, only the actual file name.
- The object search path mechanism (see Section 7) should be
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 10 -
-
-
- used instead.
-
- The _P_r_o_p_C_o_u_n_t indicates the actual number of data items
- associated with this particular attribute. After reading in
- an object, properties of type _O_F_F__D_E_F_A_U_L_T__D_A_T_A will have a
- _P_r_o_p_C_o_u_n_t of one, properties of type _O_F_F__G_E_N_E_R_I_C__D_A_T_A will
- have a _P_r_o_p_C_o_u_n_t equal to the number of generic data items
- in the list, properties of type _O_F_F__I_N_D_E_X_E_D__D_A_T_A will have a
- _P_r_o_p_C_o_u_n_t equal to the number of items in the data item
- list, and properties of type _O_F_F__I_N_D_E_X_E_D__P_O_L_Y__D_A_T_A will have
- a _P_r_o_p_C_o_u_n_t equal to the number of data items in the
- geometry list.
-
- The _D_a_t_a_F_o_r_m_a_t field contains a string of characters
- corresponding to primitive data items. The composite type
- of the data for this property can then be deduced by looking
- at this field and applying the rules for padding to word and
- half-word boundaries.
-
- The _P_r_o_p_D_a_t_a field contains a pointer to a block of
- memory containing the actual data for this property. This
- data will have the same data alignment restrictions as a
- binary file has, with the exception of strings. As strings
- are read in, memory is malloc'ed to hold them and a pointer
- to the string is stored in the appropriate field in the data
- list. This means that all primitive data types will have a
- fixed size and lengths and alignments can be computed more
- easily.
-
- The _N_e_x_t_P_r_o_p field contains a pointer to the next pro-
- perty structure in the property list.
-
- The routines contained in the subroutine library are
- defined below.
-
-
- #include "off.h"
-
- int OFFReadObj(Obj, FileName)
- OFFObjDesc *Obj;
- char *FileName;
-
- int OFFWriteObj(Obj, FileName, Directory, FileType);
- OFFObjDesc *Obj;
- char *FileName;
- char *Directory;
- int FileType;
-
- void OFFPackObj(Obj)
- OFFObjDesc *Obj;
-
- void OFFPackProperty(Property)
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 11 -
-
-
- OFFProperty *Property;
-
- int OFFReadGeneric(Property, FileName)
- OFFProperty *Property;
- char *FileName;
-
- int OFFWriteGeneric(Property, FileName, FileType)
- OFFProperty *Property;
- char *FileName;
- int FileType;
-
- int OFFReadIndexed(Property, FileName)
- OFFProperty *Property;
- char *FileName;
-
- int OFFWriteIndexed(Property, FileName, FileType)
- OFFProperty *Property;
- char *FileName;
- int FileType;
-
- int OFFReadIndexedPoly(Property, FileName)
- OFFProperty *Property;
- char *FileName;
-
- int OFFWriteIndexedPoly(Property, FileName, FileType)
- OFFProperty *Property;
- char *FileName;
- int FileType;
-
- OFFObjDesc *OFFCreateObj()
-
- int OFFDestroyObj(Obj)
- OFFObjDesc *Obj;
-
- OFFProperty *OFFAddProperty(Obj)
- OFFObjDesc *Obj;
-
- int OFFRemoveProperty(Obj, PropertyName)
- OFFObjDesc *Obj;
- char *PropertyName;
-
- int OFFFreeProperty(Property)
- OFFProperty *Property;
-
-
- _O_F_F_R_e_a_d_O_b_j will attempt to open the object header file
- named _F_i_l_e_N_a_m_e and read the object data it contains. A
- pointer to the constructed object structure will be returned
- in _O_b_j when the object has been read. An attempt will be
- made to open the specified file first as given, then con-
- catenated in turn with each of the directories specified by
- the environment search path variable _O_B_J__P_A_T_H. The property
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 12 -
-
-
- list for the object is built as the file is read. Upon
- return, the client need only traverse the property list and
- select the data it needs. This routine calls _O_F_F_R_e_a_d_G_e_n_e_r_i_c
- and _O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y in order to read associated data
- files. _O_F_F_R_e_a_d_O_b_j will return 0 if the read operation was
- successful, -1 otherwise.
-
- _O_F_F_W_r_i_t_e_O_b_j will attempt to write the object pointed at
- by _O_b_j using the filename specified by _F_i_l_e_N_a_m_e. The file
- will be written in the directory indicated by _D_i_r_e_c_t_o_r_y. If
- _F_i_l_e_T_y_p_e is _O_F_F__A_S_C_I_I, the file will be written as an ASCII
- text OFF file. If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_R_Y, the file will be
- written as a binary OFF file. The property list for the
- object is traversed and each property of the object is writ-
- ten out in turn. This routine calls _O_F_F_W_r_i_t_e_G_e_n_e_r_i_c and
- _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y in order to write associated data files.
- _O_F_F_W_r_i_t_e_O_b_j will return 0 if the write operation was suc-
- cessful, -1 otherwise.
-
- _O_F_F_P_a_c_k_O_b_j attempts to _p_a_c_k the object pointed at by
- _O_b_j. Packing only applies to geometry and normals stored in
- indexed_polygon format. See _O_F_F_P_a_c_k_P_r_o_p_e_r_t_y below.
-
- _O_F_F_P_a_c_k_P_r_o_p_e_r_t_y packs the property pointed at by _P_r_o_-
- _p_e_r_t_y. Packing can only be applied to indexed_polygon pro-
- perties with format ``fff''. (This is normally the case for
- geometry and normals properties.) Packing works by sharing
- common data (vertex or normal) values. Since each vertex
- and vertex normal of an object is usually shared by three or
- more polygons, this can save a great deal of space and
- rendering time. If _P_r_o_p_e_r_t_y could not be packed, it is not
- modified; otherwise the property data is changed in-place.
-
- _O_F_F_R_e_a_d_G_e_n_e_r_i_c will read the generic data file named
- _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains the full path name) into
- the property structure pointed at by _P_r_o_p_e_r_t_y. This routine
- will allocate the space it needs in order to read in the
- data. A pointer to this allocated data space will be stored
- in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_r_t_y as described
- earlier. The entire object, including all allocated memory
- resources can later be deallocated by calling _O_F_F_D_e_s_t_r_o_y_O_b_j.
- This routine will not typically be called directly by appli-
- cations. _O_F_F_R_e_a_d_G_e_n_e_r_i_c will return 0 if the read operation
- was successful, -1 otherwise.
-
- _O_F_F_W_r_i_t_e_G_e_n_e_r_i_c will write the generic data associated
- with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains
- the full path name of the file to be written). If _F_i_l_e_T_y_p_e
- is _O_F_F__A_S_C_I_I, the file will be written as an ASCII text gen-
- eric data file. If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_R_Y, the file will be
- written as a binary generic data file. This routine will
- not typically be called directly by applications.
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 13 -
-
-
- _O_F_F_W_r_i_t_e_G_e_n_e_r_i_c will return 0 if the write operation was
- successful, -1 otherwise.
-
- _O_F_F_R_e_a_d_I_n_d_e_x_e_d will read the indexed data file named
- _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains the full path name) into
- the property structure pointed at by _P_r_o_p_e_r_t_y. This routine
- will allocate the space it needs in order to read in the
- data. A pointer to this allocated data space will be stored
- in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_r_t_y as described
- earlier. The entire object, including all allocated memory
- resources can later be deallocated by calling _O_F_F_D_e_s_t_r_o_y_O_b_j.
- This routine will not typically be called directly by appli-
- cations. _O_F_F_R_e_a_d_I_n_d_e_x_e_d will return 0 if the read operation
- was successful, -1 otherwise.
-
- _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d will write the indexed data associated
- with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains
- the full path name of the file to be written). If _F_i_l_e_T_y_p_e
- is _O_F_F__A_S_C_I_I, the file will be written as an ASCII text
- indexed data file. If _F_i_l_e_T_y_p_e is _O_F_F__B_I_N_A_R_Y, the file will
- be written as a binary indexed data file. This routine will
- not typically be called directly by applications. _O_F_F_W_r_i_-
- _t_e_I_n_d_e_x_e_d will return 0 if the write operation was success-
- ful, -1 otherwise.
-
- _O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y will read the indexed_poly data file
- named _F_i_l_e_N_a_m_e (here _F_i_l_e_N_a_m_e contains the full path name)
- into the property structure pointed at by _P_r_o_p_e_r_t_y. This
- routine will allocate the space it needs in order to read in
- the data. A pointer to this allocated data space will be
- stored in the _P_r_o_p_D_a_t_a field of the specified _p_r_o_p_e_r_t_y as
- described earlier. The entire object, including all allo-
- cated memory resources can later be deallocated by calling
- _O_F_F_D_e_s_t_r_o_y_O_b_j. This routine will not typically be called
- directly by applications. _O_F_F_R_e_a_d_I_n_d_e_x_e_d_P_o_l_y will return 0
- if the read operation was successful, -1 otherwise.
-
- _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y will write the indexed_poly data
- associated with _P_r_o_p_e_r_t_y into the file _F_i_l_e_N_a_m_e (here
- _F_i_l_e_N_a_m_e contains the full path name of the file to be writ-
- ten). If _F_i_l_e_T_y_p_e is _O_F_F__A_S_C_I_I, the file will be written as
- an ASCII text indexed_poly data file. If _F_i_l_e_T_y_p_e is
- _O_F_F__B_I_N_A_R_Y, the file will be written as a binary
- indexed_poly data file. This routine will not typically be
- called directly by applications. _O_F_F_W_r_i_t_e_I_n_d_e_x_e_d_P_o_l_y will
- return 0 if the write operation was successful, -1 other-
- wise.
-
- _O_F_F_C_r_e_a_t_e_O_b_j allocates and initializes an _O_F_F_O_b_j_D_e_s_c
- structure A pointer to the newly-created structure is
- returned. The null pointer is returned if the operation was
- unsuccessful.
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 14 -
-
-
- _O_F_F_D_e_s_t_r_o_y_O_b_j deallocates all memory resources associ-
- ated with the object pointed at by _O_b_j. It works by calling
- _O_F_F_F_r_e_e_P_r_o_p_e_r_t_y for each property in the property list for
- the specified object.
-
- _O_F_F_A_d_d_P_r_o_p_e_r_t_y adds a property structure to the pro-
- perty list associated with the object pointed at by _O_b_j,
- initializes it, and returns a pointer to it. The null
- pointer is returned if the operation was unsuccessful.
-
- _O_F_F_R_e_m_o_v_e_P_r_o_p_e_r_t_y deletes the named property from the
- object pointed at by _O_b_j. This routine returns -1 if the
- named property is not found in the property list for the
- specified object.
-
- _O_F_F_F_r_e_e_P_r_o_p_e_r_t_y frees all the memory resources allo-
- cated to the property structure specified by _P_r_o_p_e_r_t_y as
- well as the property structure itself. This routine will
- not typically be called directly by applications.
-
- _7. _O_b_j_e_c_t _S_e_a_r_c_h _P_a_t_h
-
- It is important to avoid embedding path names in object
- files. When an object is transported to another system,
- chances are slim that the same directory structure will
- exist. The _O_F_F_R_e_a_d_O_b_j routine in libobj.a knows about an
- environment variable named _O_B_J__P_A_T_H that is used to overcome
- this problem.
-
- When an object is read, an attempt is first made to
- open it in the current working directory. If that attempt
- fails, the directories specified in the _O_B_J__P_A_T_H environment
- variable are tried in turn until the file is successfully
- opened or the directory list is exhausted. _O_B_J__P_A_T_H con-
- tains a list of directories, separated by spaces, that are
- to be searched for the named objects.
-
- The name of the directory where a successful open
- operation occurred is used for opening associated data files
- as well. This means that all of the data files for a par-
- ticular object must reside in the same directory.
-
- It is hoped that in this way, users will be able to
- draw on one or more collections of "standard" objects in
- addition to their own private collections of objects.
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 15 -
-
-
- _8. _A_p_p_e_n_d_i_x _A: _C_o_n_v_e_n_t_i_o_n_s _f_o_r _P_o_l_y_g_o_n_a_l _O_b_j_e_c_t_s
-
- This list contains the conventions we have adopted for
- describing 3D polygonal objects which are defined in some
- three-dimensional model coordinate system. Items in regular
- type are string literal, printed as they would appear in an
- OFF file, and item in italics indicate data values that will
- vary from object to object. By convention, the header for
- an ASCII OFF file is suffixed with ".aoff" and the header
- for a binary OFF file is suffixed with ".off". There are
- two choices for how colors may be stored. If they are
- stored as generic data, the suffixes used are ".{b}pcol" for
- polygon colors and ".{b}vcol" for vertex colors. If they
- are stored as indexed data, the suffixes used are
- ".{b}ipcol" and ".{b}ivcol".
-
-
- box; c|c|c|c|c|c l|l|l|l|l|l.
- Property Type Format Defaults ASCII
- filename Binary Filename =
- name ***** ***** _o_b_j_n_a_m_e ***** *****
- author ***** ***** _a_u_t_h_o_r ***** *****
- description ***** ***** _d_e_s_c_r_i_p_t_i_o_n ***** *****
- copyright ***** ***** _c_o_p_y_r_i_g_h_t ***** *****
- type ***** ***** polyline ***** *****
- ***** ***** polygon ***** *****
- geometry indexed_poly fff ***** _n_a_m_e.geom _n_a_m_e.bgeom
- polygon_colors generic fff ***** _n_a_m_e.pcol _n_a_m_e.bpcol
- vertex_colors generic fff ***** _n_a_m_e.vcol _n_a_m_e.bvcol
- polygon_colors indexed fff ***** _n_a_m_e.ipcol _n_a_m_e.bipcol
- vertex_colors indexed fff ***** _n_a_m_e.ivcol _n_a_m_e.bivcol
- back_faces default s cull ***** *****
- display ***** *****
- reverse ***** *****
- vertex_order default s clockwise ***** *****
- counter-
- clockwise ***** *****
- counterclock-
- wise ***** *****
- polygon_normals generic fff ***** _n_a_m_e.pnorm _n_a_m_e.bpnorm
- vertex_normals generic fff ***** _n_a_m_e.vnorm _n_a_m_e.bvnorm
- diffuse_coef default f _v_a_l_u_e ***** *****
- specular_coef default f _v_a_l_u_e ***** *****
- specular_power default f _v_a_l_u_e ***** *****
- bounding_box default ffffff _v_a_l_u_e ***** *****
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 16 -
-
-
- _9. _A_p_p_e_n_d_i_x _B: _O_F_F _H_e_a_d_e_r _F_i_l_e _F_o_r _a _C_u_b_e (_c_u_b_e._a_o_f_f)
-
-
-
-
-
-
-
-
- ; l l. name cube author Randi J. Rost
- description cube with sides of red, green, blue, cyan,
- yellow, magenta copyright public domain
- type polygon
-
-
- ; l c c c l c c c l l l l. # Prop. data
- type format filename or default data
- #_______ _________ ______ ________________________
-
- geometry indexed_poly fff cube.geom
- vertex_order default s clockwise
- polygon_colors generic fff cube.pcol
- back_faces default s cull
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 17 -
-
-
- _1_0. _A_p_p_e_n_d_i_x _C: _L_i_s_t_i_n_g _o_f _c_u_b_e._g_e_o_m
-
-
-
-
-
-
-
-
- ; nw(0.5i) nw(0.5i) nw(0.5i) nw(0.5i) nw(0.5i).
- 8 6 24 -1.0 -1.0 1.0 -1.0 1.0 1.0
- 1.0 1.0 1.0 1.0 -1.0 1.0 -1.0 -1.0 -1.0
- -1.0 1.0 -1.0 1.0 1.0 -1.0 1.0 -1.0 -
- 1.0 4 1 2 3 4
- 4 5 6 2 1
- 4 3 2 6 7
- 4 3 7 8 4
- 4 1 4 8 5
- 4 8 7 6 5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 18 -
-
-
- _1_1. _A_p_p_e_n_d_i_x _D: _L_i_s_t_i_n_g _o_f _c_u_b_e._p_c_o_l
-
-
-
-
-
-
-
-
- ; l s s nw(0.5i) nw(0.5i) nw(0.5i). 6 1.0
- 0.0 0.0 0.0 1.0 0.0 0.0 0.0
- 1.0 0.0 1.0 1.0 1.0 1.0 0.0 1.0
- 0.0 1.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 19 -
-
-
- _1_2. _A_p_p_e_n_d_i_x _E: _L_i_s_t_i_n_g _o_f _o_f_f._h
-
-
-
- #define OFF_INDEXED_POLY_MAGIC 0xFEEDFEEDL
- #define OFF_GENERIC_MAGIC 0xBEEFBEEFL
- #define OFF_INDEXED_MAGIC 0xBADBADBAL
-
- #define OFF_BIGSTR 256
- #define OFF_SMSTR 40
-
- #define OFF_ASCII 0
- #define OFF_BINARY 1
-
-
- /* Types of data for object properties */
-
- #define OFF_UNKNOWN_TYPE_DATA 0
- #define OFF_STANDARD_DATA 1
- #define OFF_COMMENT_DATA 2
- #define OFF_DEFAULT_DATA 3
- #define OFF_GENERIC_DATA 4
- #define OFF_INDEXED_POLY_DATA 5
- #define OFF_INDEXED_DATA 6
-
-
- typedef struct _OFFProp
- {
- char PropName[OFF_SMSTR]; /* Name of property (or attribute) */
- int PropType; /* Type of data for property */
- char PropFileName[OFF_BIGSTR];/* Name of file that has prop data */
- char DataFormat[OFF_SMSTR]; /* Pointer to property data format */
- int PropCount; /* Number of data items for property*/
- char *PropData; /* Pointer to property data */
- struct _OFFProp *NextProp; /* Pointer to next property in list */
- } OFFProperty;
-
- typedef struct
- {
- OFFProperty *FirstProp; /* Pointer to first property in list*/
- } OFFObjDesc;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 20 -
-
-
- _1_3. _A_p_p_e_n_d_i_x _F: _D_a_t_a _S_t_r_u_c_t_u_r_e _F_o_r_m_a_t
-
- The following diagram depicts some of the data struc-
- tures for the object _c_u_b_e._a_o_f_f after being read by
- _O_F_F_R_e_a_d_O_b_j() (or just prior to being written by _O_F_F_W_r_i_-
- _t_e_O_b_j()). move to 0.0, 14.5 Object: [ boxht
- = 0.3i; boxwid = 2.0i moveht = 0.3i; movewid = 0.0i
- down A: box "FirstProp" move
- up 0.3i; move right 2.0i down B: box
- ]
-
- move to 1.0, 13.0 Prop1: [ boxht = 0.3i;
- boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
- down A: box "PropName" down B:
- box "PropType" down C: box "PropFileName"
- down D: box "DataFormat" down
- E: box "PropCount" down F: box
- "PropData" down H: box "NextProp"
- move up 2.1i; move right 2.25i;
- boxht = 0.3i; boxwid = 3.0i moveht =
- 0.3i; movewid = 0.0i down I: box "name"
- down J: box "OFF_STANDARD_DATA"
- down K: box "_n_u_l_l _s_t_r_i_n_g" down L:
- box "_n_u_l_l _s_t_r_i_n_g" down M: box "0"
- down N: box down O:
- box ]
-
- move to 1.0, 10.0 Prop2: [ boxht = 0.3i;
- boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
- down A: box "PropName" down B:
- box "PropType" down C: box "PropFileName"
- down D: box "DataFormat" down
- E: box "PropCount" down F: box
- "PropData" down H: box "NextProp"
- move up 2.1i; move right 2.25i;
- boxht = 0.3i; boxwid = 3.0i moveht =
- 0.3i; movewid = 0.0i down I: box "author"
- down J: box "OFF_STANDARD_DATA"
- down K: box "_n_u_l_l _s_t_r_i_n_g" down L:
- box "_n_u_l_l _s_t_r_i_n_g" down M: box "0"
- down N: box down O:
- box ]
-
- move to 1.0, 7.0 Prop3: [ boxht = 0.3i;
- boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
- down A: box "PropName" down B:
- box "PropType" down C: box "PropFileName"
- down D: box "DataFormat" down
- E: box "PropCount" down F: box
- "PropData" down H: box "NextProp"
- move up 2.1i; move right 2.25i;
- boxht = 0.3i; boxwid = 3.0i moveht =
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 21 -
-
-
- 0.3i; movewid = 0.0i down I: box
- "geometry" down J: box
- "OFF_INDEXED_POLY_DATA" down K: box
- "cube.geom" down L: box "fff"
- down M: box "6" down N: box
- down O: box ]
-
- move to 1.0, 4.0 Prop4: [ boxht = 0.3i;
- boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
- down A: box "PropName" down B:
- box "PropType" down C: box "PropFileName"
- down D: box "DataFormat" down
- E: box "PropCount" down F: box
- "PropData" down H: box "NextProp"
- move up 2.1i; move right 2.25i;
- boxht = 0.3i; boxwid = 3.0i moveht =
- 0.3i; movewid = 0.0i down I: box
- "polygon_colors" down J: box
- "OFF_GENERIC_DATA" down K: box
- "cube.pcol" down L: box "fff"
- down M: box "6" down N: box
- down O: box ]
-
- move to 1.0, 1.0 Prop5: [ boxht = 0.3i;
- boxwid = 1.5i moveht = 0.3i; movewid = 0.0i
- down A: box "PropName" down B:
- box "PropType" down C: box "PropFileName"
- down D: box "DataFormat" down
- E: box "PropCount" down F: box
- "PropData" down H: box "NextProp"
- move up 2.1i; move right 2.25i;
- boxht = 0.3i; boxwid = 3.0i moveht =
- 0.3i; movewid = 0.0i down I: box
- "back_faces" down J: box
- "OFF_DEFAULT_DATA" down K: box "_n_u_l_l
- _s_t_r_i_n_g" down L: box "s" down
- M: box "0" down N: box
- down O: box "_n_u_l_l _p_o_i_n_t_e_r" ]
-
- line from Prop1.O.c to Prop1.O.c.x, (Prop1.s.y + Prop2.n.y)
- / 2.0 line to 0.5, (Prop1.s.y + Prop2.n.y) / 2.0 line to
- 0.5, Prop2.A.c.y arrow to Prop2.A.w
-
- line from Prop2.O.c to Prop2.O.c.x, (Prop2.s.y + Prop3.n.y)
- / 2.0 line to 0.5, (Prop2.s.y + Prop3.n.y) / 2.0 line dashed
- to 0.5, Prop3.A.c.y arrow to Prop3.A.w
-
- line from Prop3.O.c to Prop3.O.c.x, (Prop3.s.y + Prop4.n.y)
- / 2.0 line to 0.5, (Prop3.s.y + Prop4.n.y) / 2.0 line dashed
- to 0.5, Prop4.A.c.y arrow to Prop4.A.w
-
- line from Prop4.O.c to Prop4.O.c.x, (Prop4.s.y + Prop5.n.y)
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 22 -
-
-
- / 2.0 line to 0.5, (Prop4.s.y + Prop5.n.y) / 2.0 line to
- 0.5, Prop5.A.c.y arrow to Prop5.A.w
-
- line from Object.B.c to Object.B.c.x, (Object.s.y +
- Prop1.n.y) / 2.0 line to 0.5, (Object.s.y + Prop1.n.y) / 2.0
- line to 0.5, Prop1.A.c.y arrow to Prop1.A.w
-
- boxht = 0.3i; boxwid = 2.0i P1: box "cube" at Prop1.N.e.x +
- 1.5i, Prop1.N.e.y arrow from Prop1.N.c to P1.w
-
- P2: box "Randi J. Rost" at Prop2.N.e.x + 1.5i, Prop2.N.e.y
- arrow from Prop2.N.c to P2.w
-
- P3: box " 8 6 24 -1.0 -1.0" at Prop3.N.e.x + 1.5i,
- Prop3.N.e.y P4: box " 1.0 -1.0 1.0 1.0 1.0" with .nw at
- P3.sw P5: box " 1.0 1.0 1.0 -1.0 1.0" with .nw at P4.sw
- P6: box "-1.0 -1.0 -1.0 -1.0 1.0" with .nw at P5.sw P7: box
- "-1.0 1.0 1.0 -1.0 1.0" with .nw at P6.sw P8: box "-1.0
- -1.0 4 4 4 4 4 4" with .nw at P7.sw P9: box "1 2 3 4
- 5 6 2 1" with .nw at P8.sw Pa: box "3 2 6 7 3 7 8
- 4" with .nw at P9.sw Pb: box "1 4 8 5 8 7 6 5" with
- .nw at Pa.sw arrow from Prop3.N.c to P3.w
-
- Pc: box "6 1.0 0.0 0.0 0.0" at Prop4.N.e.x + 1.5i,
- Prop4.N.e.y Pd: box "1.0 0.0 0.0 0.0 1.0" with .nw at
- Pc.sw Pe: box "0.0 1.0 1.0 1.0 1.0" with .nw at Pd.sw
- Pf: box "0.0 1.0 0.0 1.0 " with .nw at Pe.sw arrow
- from Prop4.N.c to Pc.w
-
- boxht = 0.3i; boxwid = 0.5i Pg: box at Prop5.N.e.x + 1.0i,
- Prop5.N.e.y Ph: box "cull" at Pg.e.x + 1.0i, Prop5.N.e.y
- arrow from Pg.c to Ph.w arrow from Prop5.N.c to Pg.w
-
- "Object" at Object.A.n above
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-
-
-
-
- - 23 -
-
-
- _1_4. _A_c_k_n_o_w_l_e_d_g_e_m_e_n_t_s
-
- OFF is a derivative of an object file format used at
- Ohio State University. Special thanks to Allen Akin of WSE
- for helpful ideas and suggestions. Thanks also to Jeff
- Friedberg of Digital's High-Performance Workstation (HPWS)
- group and Shaun Ho of WSE who also contributed to the
- design. Danny Shapiro of WSE provided suggestions for addi-
- tional enhancements and conventions.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- April 26, 1990
-
-
-